<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
<title>自动化测试-接口测试_版本1</title><link href='https://fonts.googleapis.com/css2?family=JetBrains+Mono:ital,wght@0,400;0,700;1,400;1,700&display=swap' rel='stylesheet' type='text/css' />
<link href='./drake/font.css' rel='stylesheet' type='text/css' /><style type='text/css'>html {overflow-x: initial !important;}:root { --bg-color:#ffffff; --text-color:#333333; --select-text-bg-color:#B5D6FC; --select-text-font-color:auto; --monospace:"Lucida Console",Consolas,"Courier",monospace; }
html { font-size: 14px; background-color: var(--bg-color); color: var(--text-color); font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; }
body { margin: 0px; padding: 0px; height: auto; bottom: 0px; top: 0px; left: 0px; right: 0px; font-size: 1rem; line-height: 1.42857; overflow-x: hidden; background: inherit; tab-size: 4; }
iframe { margin: auto; }
a.url { word-break: break-all; }
a:active, a:hover { outline: 0px; }
.in-text-selection, ::selection { text-shadow: none; background: var(--select-text-bg-color); color: var(--select-text-font-color); }
#write { margin: 0px auto; height: auto; width: inherit; word-break: normal; word-wrap: break-word; position: relative; white-space: normal; overflow-x: visible; padding-top: 40px; }
#write.first-line-indent p { text-indent: 2em; }
#write.first-line-indent li p, #write.first-line-indent p * { text-indent: 0px; }
#write.first-line-indent li { margin-left: 2em; }
.for-image #write { padding-left: 8px; padding-right: 8px; }
body.typora-export { padding-left: 30px; padding-right: 30px; }
.typora-export .footnote-line, .typora-export li, .typora-export p { white-space: pre-wrap; }
@media screen and (max-width: 500px) {
  body.typora-export { padding-left: 0px; padding-right: 0px; }
  #write { padding-left: 20px; padding-right: 20px; }
  .CodeMirror-sizer { margin-left: 0px !important; }
  .CodeMirror-gutters { display: none !important; }
}
#write li > figure:first-child { margin-top: -20px; }
#write ol, #write ul { position: relative; }
img { max-width: 100%; vertical-align: middle; }
button, input, select, textarea { color: inherit; font-style: inherit; font-variant: inherit; font-weight: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; }
input[type="checkbox"], input[type="radio"] { line-height: normal; padding: 0px; }
*, ::after, ::before { box-sizing: border-box; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p, #write pre { width: inherit; }
#write h1, #write h2, #write h3, #write h4, #write h5, #write h6, #write p { position: relative; }
h1, h2, h3, h4, h5, h6 { break-after: avoid-page; break-inside: avoid; orphans: 2; }
p { orphans: 4; }
h1 { font-size: 2rem; }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.6rem; }
h4 { font-size: 1.4rem; }
h5 { font-size: 1.2rem; }
h6 { font-size: 1rem; }
.md-math-block, .md-rawblock, h1, h2, h3, h4, h5, h6, p { margin-top: 1rem; margin-bottom: 1rem; }
.hidden { display: none; }
.md-blockmeta { color: rgb(204, 204, 204); font-weight: 700; font-style: italic; }
a { cursor: pointer; }
sup.md-footnote { padding: 2px 4px; background-color: rgba(238, 238, 238, 0.7); color: rgb(85, 85, 85); border-radius: 4px; cursor: pointer; }
sup.md-footnote a, sup.md-footnote a:hover { color: inherit; text-transform: inherit; text-decoration: inherit; }
#write input[type="checkbox"] { cursor: pointer; width: inherit; height: inherit; }
figure { overflow-x: auto; margin: 1.2em 0px; max-width: calc(100% + 16px); padding: 0px; }
figure > table { margin: 0px !important; }
tr { break-inside: avoid; break-after: auto; }
thead { display: table-header-group; }
table { border-collapse: collapse; border-spacing: 0px; width: 100%; overflow: auto; break-inside: auto; text-align: left; }
table.md-table td { min-width: 32px; }
.CodeMirror-gutters { border-right: 0px; background-color: inherit; }
.CodeMirror-linenumber { user-select: none; }
.CodeMirror { text-align: left; }
.CodeMirror-placeholder { opacity: 0.3; }
.CodeMirror pre { padding: 0px 4px; }
.CodeMirror-lines { padding: 0px; }
div.hr:focus { cursor: none; }
#write pre { white-space: pre-wrap; }
#write.fences-no-line-wrapping pre { white-space: pre; }
#write pre.ty-contain-cm { white-space: normal; }
.CodeMirror-gutters { margin-right: 4px; }
.md-fences { font-size: 0.9rem; display: block; break-inside: avoid; text-align: left; overflow: visible; white-space: pre; background: inherit; position: relative !important; }
.md-diagram-panel { width: 100%; margin-top: 10px; text-align: center; padding-top: 0px; padding-bottom: 8px; overflow-x: auto; }
#write .md-fences.mock-cm { white-space: pre-wrap; }
.md-fences.md-fences-with-lineno { padding-left: 0px; }
#write.fences-no-line-wrapping .md-fences.mock-cm { white-space: pre; overflow-x: auto; }
.md-fences.mock-cm.md-fences-with-lineno { padding-left: 8px; }
.CodeMirror-line, twitterwidget { break-inside: avoid; }
.footnotes { opacity: 0.8; font-size: 0.9rem; margin-top: 1em; margin-bottom: 1em; }
.footnotes + .footnotes { margin-top: 0px; }
.md-reset { margin: 0px; padding: 0px; border: 0px; outline: 0px; vertical-align: top; background: 0px 0px; text-decoration: none; text-shadow: none; float: none; position: static; width: auto; height: auto; white-space: nowrap; cursor: inherit; -webkit-tap-highlight-color: transparent; line-height: normal; font-weight: 400; text-align: left; box-sizing: content-box; direction: ltr; }
li div { padding-top: 0px; }
blockquote { margin: 1rem 0px; }
li .mathjax-block, li p { margin: 0.5rem 0px; }
li { margin: 0px; position: relative; }
blockquote > :last-child { margin-bottom: 0px; }
blockquote > :first-child, li > :first-child { margin-top: 0px; }
.footnotes-area { color: rgb(136, 136, 136); margin-top: 0.714rem; padding-bottom: 0.143rem; white-space: normal; }
#write .footnote-line { white-space: pre-wrap; }
@media print {
  body, html { border: 1px solid transparent; height: 99%; break-after: avoid; break-before: avoid; }
  #write { margin-top: 0px; padding-top: 0px; border-color: transparent !important; }
  .typora-export * { -webkit-print-color-adjust: exact; }
  html.blink-to-pdf { font-size: 13px; }
  .typora-export #write { padding-left: 32px; padding-right: 32px; padding-bottom: 0px; break-after: avoid; }
  .typora-export #write::after { height: 0px; }
  @page { margin: 20mm 0px; }
}
.footnote-line { margin-top: 0.714em; font-size: 0.7em; }
a img, img a { cursor: pointer; }
pre.md-meta-block { font-size: 0.8rem; min-height: 0.8rem; white-space: pre-wrap; background: rgb(204, 204, 204); display: block; overflow-x: hidden; }
p > .md-image:only-child:not(.md-img-error) img, p > img:only-child { display: block; margin: auto; }
p > .md-image:only-child { display: inline-block; width: 100%; }
#write .MathJax_Display { margin: 0.8em 0px 0px; }
.md-math-block { width: 100%; }
.md-math-block:not(:empty)::after { display: none; }
[contenteditable="true"]:active, [contenteditable="true"]:focus { outline: 0px; box-shadow: none; }
.md-task-list-item { position: relative; list-style-type: none; }
.task-list-item.md-task-list-item { padding-left: 0px; }
.md-task-list-item > input { position: absolute; top: 0px; left: 0px; margin-left: -1.2em; margin-top: calc(1em - 10px); border: none; }
.math { font-size: 1rem; }
.md-toc { min-height: 3.58rem; position: relative; font-size: 0.9rem; border-radius: 10px; }
.md-toc-content { position: relative; margin-left: 0px; }
.md-toc-content::after, .md-toc::after { display: none; }
.md-toc-item { display: block; color: rgb(65, 131, 196); }
.md-toc-item a { text-decoration: none; }
.md-toc-inner:hover { text-decoration: underline; }
.md-toc-inner { display: inline-block; cursor: pointer; }
.md-toc-h1 .md-toc-inner { margin-left: 0px; font-weight: 700; }
.md-toc-h2 .md-toc-inner { margin-left: 2em; }
.md-toc-h3 .md-toc-inner { margin-left: 4em; }
.md-toc-h4 .md-toc-inner { margin-left: 6em; }
.md-toc-h5 .md-toc-inner { margin-left: 8em; }
.md-toc-h6 .md-toc-inner { margin-left: 10em; }
@media screen and (max-width: 48em) {
  .md-toc-h3 .md-toc-inner { margin-left: 3.5em; }
  .md-toc-h4 .md-toc-inner { margin-left: 5em; }
  .md-toc-h5 .md-toc-inner { margin-left: 6.5em; }
  .md-toc-h6 .md-toc-inner { margin-left: 8em; }
}
a.md-toc-inner { font-size: inherit; font-style: inherit; font-weight: inherit; line-height: inherit; }
.footnote-line a:not(.reversefootnote) { color: inherit; }
.md-attr { display: none; }
.md-fn-count::after { content: "."; }
code, pre, samp, tt { font-family: var(--monospace); }
kbd { margin: 0px 0.1em; padding: 0.1em 0.6em; font-size: 0.8em; color: rgb(36, 39, 41); background: rgb(255, 255, 255); border: 1px solid rgb(173, 179, 185); border-radius: 3px; box-shadow: rgba(12, 13, 14, 0.2) 0px 1px 0px, rgb(255, 255, 255) 0px 0px 0px 2px inset; white-space: nowrap; vertical-align: middle; }
.md-comment { color: rgb(162, 127, 3); opacity: 0.8; font-family: var(--monospace); }
code { text-align: left; vertical-align: initial; }
a.md-print-anchor { white-space: pre !important; border-width: initial !important; border-style: none !important; border-color: initial !important; display: inline-block !important; position: absolute !important; width: 1px !important; right: 0px !important; outline: 0px !important; background: 0px 0px !important; text-decoration: initial !important; text-shadow: initial !important; }
.md-inline-math .MathJax_SVG .noError { display: none !important; }
.html-for-mac .inline-math-svg .MathJax_SVG { vertical-align: 0.2px; }
.md-math-block .MathJax_SVG_Display { text-align: center; margin: 0px; position: relative; text-indent: 0px; max-width: none; max-height: none; min-height: 0px; min-width: 100%; width: auto; overflow-y: hidden; display: block !important; }
.MathJax_SVG_Display, .md-inline-math .MathJax_SVG_Display { width: auto; margin: inherit; display: inline-block !important; }
.MathJax_SVG .MJX-monospace { font-family: var(--monospace); }
.MathJax_SVG .MJX-sans-serif { font-family: sans-serif; }
.MathJax_SVG { display: inline; font-style: normal; font-weight: 400; line-height: normal; zoom: 90%; text-indent: 0px; text-align: left; text-transform: none; letter-spacing: normal; word-spacing: normal; word-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; }
.MathJax_SVG * { transition: none; }
.MathJax_SVG_Display svg { vertical-align: middle !important; margin-bottom: 0px !important; }
.os-windows.monocolor-emoji .md-emoji { font-family: "Segoe UI Symbol", sans-serif; }
.md-diagram-panel > svg { max-width: 100%; }
[lang="mermaid"] svg, [lang="flow"] svg { max-width: 100%; }
[lang="mermaid"] .node text { font-size: 1rem; }
table tr th { border-bottom: 0px; }
video { max-width: 100%; display: block; margin: 0px auto; }
iframe { max-width: 100%; width: 100%; border: none; }
.highlight td, .highlight tr { border: 0px; }


.CodeMirror { height: auto; }
.CodeMirror.cm-s-inner { background: inherit; }
.CodeMirror-scroll { overflow-y: hidden; overflow-x: auto; z-index: 3; }
.CodeMirror-gutter-filler, .CodeMirror-scrollbar-filler { background-color: rgb(255, 255, 255); }
.CodeMirror-gutters { border-right: 1px solid rgb(221, 221, 221); background: inherit; white-space: nowrap; }
.CodeMirror-linenumber { padding: 0px 3px 0px 5px; text-align: right; color: rgb(153, 153, 153); }
.cm-s-inner .cm-keyword { color: rgb(119, 0, 136); }
.cm-s-inner .cm-atom, .cm-s-inner.cm-atom { color: rgb(34, 17, 153); }
.cm-s-inner .cm-number { color: rgb(17, 102, 68); }
.cm-s-inner .cm-def { color: rgb(0, 0, 255); }
.cm-s-inner .cm-variable { color: rgb(0, 0, 0); }
.cm-s-inner .cm-variable-2 { color: rgb(0, 85, 170); }
.cm-s-inner .cm-variable-3 { color: rgb(0, 136, 85); }
.cm-s-inner .cm-string { color: rgb(170, 17, 17); }
.cm-s-inner .cm-property { color: rgb(0, 0, 0); }
.cm-s-inner .cm-operator { color: rgb(152, 26, 26); }
.cm-s-inner .cm-comment, .cm-s-inner.cm-comment { color: rgb(170, 85, 0); }
.cm-s-inner .cm-string-2 { color: rgb(255, 85, 0); }
.cm-s-inner .cm-meta { color: rgb(85, 85, 85); }
.cm-s-inner .cm-qualifier { color: rgb(85, 85, 85); }
.cm-s-inner .cm-builtin { color: rgb(51, 0, 170); }
.cm-s-inner .cm-bracket { color: rgb(153, 153, 119); }
.cm-s-inner .cm-tag { color: rgb(17, 119, 0); }
.cm-s-inner .cm-attribute { color: rgb(0, 0, 204); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(0, 0, 255); }
.cm-s-inner .cm-quote, .cm-s-inner.cm-quote { color: rgb(0, 153, 0); }
.cm-s-inner .cm-hr, .cm-s-inner.cm-hr { color: rgb(153, 153, 153); }
.cm-s-inner .cm-link, .cm-s-inner.cm-link { color: rgb(0, 0, 204); }
.cm-negative { color: rgb(221, 68, 68); }
.cm-positive { color: rgb(34, 153, 34); }
.cm-header, .cm-strong { font-weight: 700; }
.cm-del { text-decoration: line-through; }
.cm-em { font-style: italic; }
.cm-link { text-decoration: underline; }
.cm-error { color: red; }
.cm-invalidchar { color: red; }
.cm-constant { color: rgb(38, 139, 210); }
.cm-defined { color: rgb(181, 137, 0); }
div.CodeMirror span.CodeMirror-matchingbracket { color: rgb(0, 255, 0); }
div.CodeMirror span.CodeMirror-nonmatchingbracket { color: rgb(255, 34, 34); }
.cm-s-inner .CodeMirror-activeline-background { background: inherit; }
.CodeMirror { position: relative; overflow: hidden; }
.CodeMirror-scroll { height: 100%; outline: 0px; position: relative; box-sizing: content-box; background: inherit; }
.CodeMirror-sizer { position: relative; }
.CodeMirror-gutter-filler, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-vscrollbar { position: absolute; z-index: 6; display: none; }
.CodeMirror-vscrollbar { right: 0px; top: 0px; overflow: hidden; }
.CodeMirror-hscrollbar { bottom: 0px; left: 0px; overflow: hidden; }
.CodeMirror-scrollbar-filler { right: 0px; bottom: 0px; }
.CodeMirror-gutter-filler { left: 0px; bottom: 0px; }
.CodeMirror-gutters { position: absolute; left: 0px; top: 0px; padding-bottom: 30px; z-index: 3; }
.CodeMirror-gutter { white-space: normal; height: 100%; box-sizing: content-box; padding-bottom: 30px; margin-bottom: -32px; display: inline-block; }
.CodeMirror-gutter-wrapper { position: absolute; z-index: 4; background: 0px 0px !important; border: none !important; }
.CodeMirror-gutter-background { position: absolute; top: 0px; bottom: 0px; z-index: 4; }
.CodeMirror-gutter-elt { position: absolute; cursor: default; z-index: 4; }
.CodeMirror-lines { cursor: text; }
.CodeMirror pre { border-radius: 0px; border-width: 0px; background: 0px 0px; font-family: inherit; font-size: inherit; margin: 0px; white-space: pre; word-wrap: normal; color: inherit; z-index: 2; position: relative; overflow: visible; }
.CodeMirror-wrap pre { word-wrap: break-word; white-space: pre-wrap; word-break: normal; }
.CodeMirror-code pre { border-right: 30px solid transparent; width: fit-content; }
.CodeMirror-wrap .CodeMirror-code pre { border-right: none; width: auto; }
.CodeMirror-linebackground { position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px; z-index: 0; }
.CodeMirror-linewidget { position: relative; z-index: 2; overflow: auto; }
.CodeMirror-wrap .CodeMirror-scroll { overflow-x: hidden; }
.CodeMirror-measure { position: absolute; width: 100%; height: 0px; overflow: hidden; visibility: hidden; }
.CodeMirror-measure pre { position: static; }
.CodeMirror div.CodeMirror-cursor { position: absolute; visibility: hidden; border-right: none; width: 0px; }
.CodeMirror div.CodeMirror-cursor { visibility: hidden; }
.CodeMirror-focused div.CodeMirror-cursor { visibility: inherit; }
.cm-searching { background: rgba(255, 255, 0, 0.4); }
@media print {
  .CodeMirror div.CodeMirror-cursor { visibility: hidden; }
}


:root { --monospace: "Iosevka Curly", "JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, "Ubuntu Mono", Consolas, HYZhengYuan; --text-font: var(--monospace); --title-font: var(--monospace); --latex-font: var(--monospace); --text-line-height: 1.6; --code-line-height: 1.6; --p-spacing: 0.8rem; --file-tree-text-size: 1.1rem; --toc-text-size: 1rem; --text-size: 14px; }


:root { --text-color: #333333; --bg-color: #ffffff; --control-text-color: var(--text-color); --meta-content-color: var(--text-color); --active-file-border-color: var(--drake-accent); --rawblock-edit-panel-bd: var(--code-block-bg-color); --item-hover-bg-color: #E5E5E596; --active-file-bg-color: var(--item-hover-bg-color); --blur-text-color: rgba(51, 51, 51, 0.5); --drake-accent: #e95f59; --drake-highlight: #d63200; --a-color: var(--drake-highlight); --variable-color: var(--drake-highlight); --outline-active-color: var(--a-color); --code-block-bg-color: #2b2b2b; --code-block-color: #A9B7C6; --title-color: #273849; --blockquote-border-color: var(--drake-accent); --blockquote-color: var(--text-color); --blockquote-bg-color: #fdefee; --strong-color: var(--title-color); --h2-underline-color: var(--title-color); --horizontal-divider-color: var(--title-color); --height-light-color: var(--drake-highlight); --height-light-border-color: var(--drake-highlight); --yaml-color: #777777; --yaml-bg-color: #f7f7f7; --footnotes-bg-color: #3c3d3e; --footnotes-highlight: #FFD760; --table-border-color: #dfe2e5; --table-header-bg-color: #f8f8f8; --table-bg-color: var(--bg-color); --table-n2-bg-color: #f8f8f8; --input-bg-color: var(--item-hover-bg-color); --btn-hover-bg-color: var(--item-hover-bg-color); --checkbox-checked: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M425.984 726.016l384-384-59.99-61.995-324.01 324.011-152.021-152.021L213.973 512zm384-598.016q36.01 0 61.013 25.984T896 213.974v596.01q0 34.005-25.003 59.99t-61.013 25.983h-596.01q-36.011 0-61.014-25.984t-25.003-59.989v-596.01q0-34.006 25.003-59.99T213.973 128h596.011z' fill='%2365b73b'/%3E%3C/svg%3E"); --checkbox-unchecked: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M810.667 213.333v597.334H213.333V213.333h597.334m0-85.333H213.333C166.4 128 128 166.4 128 213.333v597.334C128 857.6 166.4 896 213.333 896h597.334C857.6 896 896 857.6 896 810.667V213.333C896 166.4 857.6 128 810.667 128z' fill='%23333333'/%3E%3C/svg%3E"); }
html { font-size: var(--text-size); }
body { color: var(--text-color); font-feature-settings: "liga", "calt"; -webkit-font-smoothing: subpixel-antialiased; text-rendering: optimizeLegibility; letter-spacing: 0px; margin: 0px; overflow-x: hidden; font-family: var(--text-font)  !important; }
p { line-height: var(--text-line-height); }
.md-fences { font-size: 1rem; border-radius: 2px; word-wrap: normal; background-color: var(--code-block-bg-color); color: var(--code-block-color); border: none; line-height: var(--code-line-height); padding: 0.5rem !important; }
.on-focus-mode .CodeMirror.cm-s-inner:not(.CodeMirror-focused) *, .on-focus-mode .md-fences.md-focus .CodeMirror-code > :not(.CodeMirror-activeline) *, .on-focus-mode .md-htmlblock.md-focus .CodeMirror-code > :not(.CodeMirror-activeline) * { color: rgb(144, 144, 144) !important; }
.MathJax { font-size: 120% !important; }
.MathJax text, .MathJax use { font-family: var(--latex-font); }
.md-math-block .MathJax { font-size: 130% !important; }
[id^="mermaidChart"] .cluster rect { fill: var(--table-n2-bg-color)  !important; stroke: var(--table-border-color)  !important; }
[id^="mermaidChart"] .grid .tick text, [id^="mermaidChart"] .titleText { fill: var(--text-color)  !important; }
[id^="mermaidChart"] .clusters span.nodeLabel { line-height: 1.8rem; color: var(--text-color)  !important; }
[mermaid-type="journey"] line { stroke: rgb(122, 122, 122) !important; }
[mermaid-type="journey"] .label { color: rgb(51, 51, 51) !important; }
[id^="mermaidChart"] .relationshipLabelBox { fill: var(--bg-color)  !important; opacity: 1 !important; background-color: var(--bg-color)  !important; }
[id^="mermaidChart"] .legend { fill: var(--text-color)  !important; }
[id^="mermaidChart"] g.label { font-size: 1rem !important; }
[id^="mermaidChart"] line.divider { stroke: var(--table-border-color)  !important; }
[id^="mermaidChart"] span.nodeLabel { line-height: 1.8rem; color: var(--code-block-color)  !important; }
tspan { color: var(--text-color) ; }
[id^="mermaidChart"] .entityLabel { fill: var(--code-block-color)  !important; }
[id^="mermaidChart"] { fill: var(--text-color)  !important; }
[id^="mermaidChart"] rect.rect { fill: rgba(175, 255, 212, 0.3) !important; }
.md-diagram-panel-preview text.actor > tspan { fill: var(--code-block-color)  !important; stroke: none !important; font-family: var(--text-font)  !important; font-size: 1rem !important; }
.md-diagram-panel-preview .actor, .md-diagram-panel-preview .entityBox { stroke: var(--table-border-color)  !important; fill: var(--code-block-bg-color)  !important; }
.md-diagram-panel-preview .actor-line { stroke-width: 1px; stroke: var(--text-color)  !important; }
.md-diagram-panel-preview .messageLine0 { stroke-width: 1.5; stroke-dasharray: none; stroke: var(--text-color)  !important; }
.md-diagram-panel-preview .messageLine1 { stroke-width: 1.5 !important; stroke-dasharray: 2, 2 !important; stroke: var(--text-color)  !important; }
.md-diagram-panel-preview .messageText { fill: var(--text-color)  !important; font-family: var(--text-font)  !important; font-size: 1rem !important; }
.md-diagram-panel-preview .activation0 { fill: rgb(230, 230, 230) !important; stroke: var(--text-color)  !important; }
.md-diagram-panel-preview .labelText, .md-diagram-panel-preview .labelText > tspan { dominant-baseline: unset; alignment-baseline: unset; fill: var(--code-block-color)  !important; font-family: var(--text-font)  !important; font-size: 1rem !important; }
.md-diagram-panel-preview .labelBox { stroke: var(--table-border-color)  !important; fill: var(--code-block-bg-color)  !important; }
.md-diagram-panel-preview .loopLine { stroke: var(--text-color)  !important; }
.md-diagram-panel-preview .loopText, .md-diagram-panel-preview .loopText > tspan { fill: var(--text-color)  !important; font-size: 1rem !important; }
.md-diagram-panel-preview .sequenceNumber { fill: var(--bg-color)  !important; }
pre.md-fences-advanced.md-focus .md-fences-adv-panel { border: none; }
.md-diagram-panel-preview .edgePath .path { stroke: var(--text-color)  !important; }
.md-diagram-panel-preview .edgeLabel rect { fill: var(--bg-color)  !important; }
.md-diagram-panel-preview .edgeLabel span { color: var(--text-color)  !important; background: var(--bg-color)  !important; }
.md-diagram-panel-preview .node rect, .md-diagram-panel-preview .node circle, .md-diagram-panel-preview .node ellipse, .md-diagram-panel-preview .node polygon, .md-diagram-panel-preview .node path { stroke: var(--table-border-color)  !important; fill: var(--code-block-bg-color)  !important; }
#write .md-diagram-panel .md-diagram-panel-preview div { color: var(--code-block-color); font-family: var(--text-font)  !important; font-size: 1rem !important; }
#write code, tt { margin: 0px 2px; color: var(--drake-highlight); }
var { color: var(--variable-color); font-weight: bold; }
.md-rawblock-control:not(.md-rawblock-tooltip) { border-radius: 2px 0px 2px 2px; padding: 0.2rem !important; }
.md-rawblock:hover > .md-rawblock-container { background: none; }
.md-rawblock-input { font-size: 1rem; }
.md-rawblock-tooltip-btn:hover { background: none; }
.md-rawblock:hover > .md-rawblock-tooltip { border-radius: 2px 2px 0px 0px; margin-bottom: 2px !important; }
.md-rawblock-tooltip.md-rawblock-control { border-radius: 2px 2px 0px 0px; color: var(--code-block-color); }
.md-rawblock-tooltip-name { color: var(--code-block-color); opacity: 1; }
blockquote::before { display: block; position: absolute; content: ""; width: 4px; left: 0px; top: 0px; height: 100%; background-color: var(--blockquote-border-color); border-radius: 2px; }
blockquote { color: var(--blockquote-color); border-radius: 2px; padding: 10px 16px; background-color: var(--blockquote-bg-color); position: relative; border-left: none; }
strong { color: var(--strong-color); font-weight: bold; }
#write blockquote strong { color: var(--blockquote-color); }
#write a { color: var(--a-color); text-decoration: none; }
#write h2 a .md-plain { border-bottom: 0.2rem solid var(--a-color); }
.on-focus-mode #write a .md-plain, .on-focus-mode .md-htmlblock-container a:hover { border-bottom: 0.1rem solid var(--blur-text-color); }
#write a .md-plain, .md-htmlblock-container a:hover, .on-focus-mode #write .md-focus a .md-plain, .md-focus .md-htmlblock-container a:hover { border-bottom: 0.1rem solid var(--a-color); }
[md-inline="link"] a { margin: 0px 0.2rem; }
a:any-link { color: var(--a-color); }
img { border-left: none; border-right: none; vertical-align: baseline; border-radius: 2px; }
#write { max-width: 1200px; margin: 0px auto; padding: 20px 30px 100px; }
#typora-source .CodeMirror-lines { max-width: 1200px; }
#write > ul:first-child, #write > ol:first-child { margin-top: 30px; }
body > :first-child { margin-top: 0px !important; }
body > :last-child { margin-bottom: 0px !important; }
h1, h2, h3, h4, h5, h6 { font-family: var(--title-font); position: relative; margin-top: 2rem; margin-bottom: 1rem; font-weight: bold; line-height: 1.4; cursor: text; color: var(--title-color); }
h3.md-focus::before, h4.md-focus::before, h5.md-focus::before, h6.md-focus::before { visibility: hidden; }
h1 { font-size: 2rem; text-align: center; margin-top: 0px; }
h2 { font-size: 1.8rem; margin-bottom: 1.5rem; }
.on-focus-mode h2.md-end-block.md-heading:not(.md-focus):not(.md-focus-container)::after { background-color: var(--blur-text-color)  !important; }
h3 { font-size: 1.4rem; }
h4 { font-size: 1.2rem; }
h5 { font-size: 1rem; }
h6 { font-size: 1rem; }
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { text-decoration: none; }
h1 tt, h1 code { font-size: inherit !important; }
h2 tt, h2 code { font-size: inherit !important; }
h3 tt, h3 code { font-size: inherit !important; }
h4 tt, h4 code { font-size: inherit !important; }
h5 tt, h5 code { font-size: inherit !important; }
h6 tt, h6 code { font-size: inherit !important; }
p, blockquote, ul, ol, dl, table { margin: var(--p-spacing) 0; }
li > ol, li > ul { margin: 0px; }
li { margin: 0.5em 0px; }
hr { height: 2px; padding: 0px; margin: 16px 0px; background-color: var(--horizontal-divider-color); border: 0px none; overflow: hidden; box-sizing: content-box; }
body > h2:first-child { margin-top: 0px; padding-top: 0px; }
body > h1:first-child { margin-top: 0px; padding-top: 0px; }
body > h1:first-child + h2 { margin-top: 0px; padding-top: 0px; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { margin-top: 0px; padding-top: 0px; }
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { margin-top: 0px; padding-top: 0px; }
h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { margin-top: 0px; }
li p.first { display: inline-block; }
ul, ol { }
ul:first-child, ol:first-child { margin-top: 0px; }
ul:last-child, ol:last-child { margin-bottom: 0px; }
.ty-table-edit { margin-top: -1rem !important; }
#write table { margin-top: 1rem; word-break: initial; background-color: var(--table-bg-color); }
table tr { border-top: 0.1em solid var(--table-border-color); margin: 0px; padding: 0px; }
table th { font-weight: bold; border-top: 0.1em solid var(--table-border-color); border-right: 0.1em solid var(--table-border-color); border-left: 0.1em solid var(--table-border-color); border-image: 0.1em solid var(--table-border-color); border-bottom: 0px; margin: 0px; padding: 6px 13px; }
table td { border: 0.1em solid var(--table-border-color); margin: 0px; padding: 6px 13px; }
table thead { background-color: var(--table-header-bg-color); }
table tr:nth-child(2n) { background-color: var(--table-n2-bg-color); }
table tr th:first-child, table tr td:first-child { margin-top: 0px; }
table tr th:last-child, table tr td:last-child { margin-bottom: 0px; }
#write em { padding: 0px 5px 0px 2px; }
#write mark { border: 0.1em solid var(--height-light-border-color); color: var(--height-light-color); background-color: transparent; padding: 0.1rem 0.5rem; border-radius: 2rem; margin: 0px 0.2rem; font-size: 0.95rem; }
kbd { border: 0.1em solid rgb(91, 91, 94); background: transparent; color: var(--text-color); margin: 0px 0.4rem; font-size: 0.95rem; padding: 0.3em 0.4em; border-radius: 0.4em; box-shadow: rgba(0, 0, 0, 0.3) 0.1em 0.1em 0.2em; font-family: var(--text-font)  !important; }
#write del { padding: 1px 2px; }
.md-task-list-item > input { margin-left: -1.3em; }
@media print {
  html { font-size: 12px; }
  table, pre { break-inside: avoid; }
  pre { word-wrap: break-word; }
}
#write pre.md-meta-block { padding: 1rem; font-size: 1rem; line-height: 1.45; background-color: var(--yaml-bg-color); border: 0px; border-radius: 2px; color: var(--yaml-color); margin-top: 0px !important; }
.mathjax-block > .code-tooltip { bottom: 0.375rem; }
#write > h3.md-focus::before { left: -1.5625rem; top: 0.375rem; }
#write > h4.md-focus::before { left: -1.5625rem; top: 0.285714rem; }
#write > h5.md-focus::before { left: -1.5625rem; top: 0.285714rem; }
#write > h6.md-focus::before { left: -1.5625rem; top: 0.285714rem; }
.md-image > .md-meta { border-radius: 2px; font-family: initial; padding: 2px 0px 0px 4px; color: inherit; }
.md-tag { color: inherit; }
.md-toc { margin-top: 20px; padding-bottom: 20px; }
.typora-quick-open-item { height: 50px; padding-left: 8px; padding-top: 4px; padding-bottom: 4px; font-size: 1rem !important; }
#typora-quick-open { box-shadow: rgba(0, 0, 0, 0.27) 0px 0px 8px; padding: 0px; }
.ty-quick-open-category.ty-has-prev .ty-quick-open-category-title { border-top: none; }
#typora-quick-open-input { margin: 8px; box-shadow: none; border-radius: 2px; }
#typora-quick-open-input input { font-size: 1rem; box-shadow: none; padding-top: 2px; padding-left: 10px; padding-right: 10px; line-height: 32px; max-height: 32px; border: none; }
.modal-dialog#typora-quick-open { border-radius: 8px; }
.ty-quick-open-category-title { padding-left: 8px; color: rgb(190, 190, 190); font-size: 0.8rem; margin-bottom: 4px; }
.typora-quick-open-item-path { font-size: 0.8rem; text-overflow: ellipsis; white-space: nowrap; margin-top: 1px; }
.export-detail, .export-item.active, .export-items-list-control { background: var(--active-file-bg-color)  !important; }
.cm-s-typora-default .CodeMirror-activeline-background, .typora-sourceview-on #toggle-sourceview-btn { background: var(--active-file-bg-color); }
.form-control { border: none; border-radius: 2px; box-shadow: none; }
#md-searchpanel .btn { border-radius: 2px; }
#search-panel-replaceall-btn { padding-right: 5px !important; text-align: center !important; }
#search-panel-replace-btn { text-align: center !important; }
#md-searchpanel input { background: var(--input-bg-color); border-radius: 2px; }
.searchpanel-search-option-btn { border-radius: 2px; border: none; background: transparent; color: var(--text-color); }
.searchpanel-search-option-btn.active { background: var(--text-color); color: var(--bg-color); }
.form-control:focus { box-shadow: none; }
#md-notification::before { top: 10px; }
.on-focus-mode blockquote { border-left-color: rgba(85, 85, 85, 0.12); }
header, .context-menu, .megamenu-content, footer { font-family: initial; }
.file-library-node.file-tree-node.file-node-root { font-size: var(--file-tree-text-size); }
.file-node-content:hover .file-node-icon, .file-node-content:hover .file-node-open-state { visibility: visible; }
.file-node-content { display: flex; align-items: center; }
.file-node-open-state { margin-right: 0.5rem; }
.file-node-icon { margin-right: 0.5rem; }
#typora-sidebar { font-size: inherit; font-family: var(--title-font); }
.sidebar-tabs { border-bottom: none; }
.file-list-item-summary, .file-list-item-parent-loc, .file-list-item-time, .file-list-item-summary { font-family: var(--text-font); font-size: 0.9rem !important; }
.file-list-item-file-ext-part { display: none; }
.outline-item { font-size: var(--toc-text-size); }
#write .md-footnote { background-color: inherit; color: var(--drake-highlight); font-size: 0.9rem; border-radius: 0.9rem; padding-left: 0px; }
#write .md-footnote::before { content: "["; }
#write .md-footnote::after { content: "]"; }
.md-hover-tip .code-tooltip-content { border-radius: 2px; }
span.md-def-name { padding-right: 3ch; padding-left: 0px; position: relative; font-weight: normal; }
.footnotes { font-size: 1rem; font-weight: normal; color: var(--text-color); position: relative; }
.code-tooltip-content .md-plain { font-size: 0.9rem; font-family: inherit; }
.code-tooltip-content code { padding: 0px 2px; font-family: inherit; color: var(--footnotes-highlight); background-color: inherit; }
.code-tooltip-content a { color: var(--footnotes-highlight); }
div.code-tooltip-content { box-shadow: rgba(0, 0, 0, 0.27) 0px 0px 8px; background: var(--footnotes-bg-color); }
.footnotes { opacity: 1; }
.md-def-name::after { content: ". ^"; color: var(--text-color); }
.md-def-footnote .md-def-name::before { content: ""; color: var(--text-color); position: absolute; }
.md-def-name::before { content: ""; color: var(--text-color); position: absolute; }
.md-content.md-url, .md-def-content.md-def-url.md-auto-disp { text-decoration: none; border-bottom: 0.1rem solid var(--text-color); }
.CodeMirror-scroll::-webkit-scrollbar { display: none; }
.file-list-item-summary { font-size: 1em; }
.pin-outline #outline-content .outline-active strong, .pin-outline .outline-active { font-weight: 500; color: var(--outline-active-color); }
.file-list-item.active { border-left: 4px solid var(--drake-accent); }
#md-searchpanel .btn:not(.close-btn):hover { box-shadow: none; background: var(--btn-hover-bg-color); }
#write input[type="checkbox"] { opacity: 0; height: 1.6rem; width: 1.6rem; margin-left: -2em; margin-top: 0px; top: 0px; }
#write .ul-list li.md-task-list-item.task-list-done::before { content: ""; background-image: ; background-position: var(--checkbox-checked) 0 0 no-repeat; background-repeat: var(--checkbox-checked) 0 0 no-repeat; background-attachment: ; background-origin: ; background-clip: ; background-color: ; background-size: 100%; display: inline-block; position: absolute; height: 1.6rem; width: 1.6rem; margin-left: -2em; }
#write .ul-list li.md-task-list-item.task-list-not-done::before { content: ""; background-image: ; background-position: var(--checkbox-unchecked) 0 0 no-repeat; background-repeat: var(--checkbox-unchecked) 0 0 no-repeat; background-attachment: ; background-origin: ; background-clip: ; background-color: ; background-size: 100%; display: inline-block; position: absolute; height: 1.6rem; width: 1.6rem; margin-left: -2em; }
.task-list-item p { line-height: 1.6rem; }
.btn { border-radius: 2px; }
.modal-content { border-radius: 8px; }
.btn-primary:hover, .btn-primary:active { background-color: var(--btn-hover-bg-color); color: var(--drake-highlight); }
.btn-primary { background-color: transparent; color: var(--drake-highlight); }
.btn-default { background-color: transparent; }
.btn:active { box-shadow: none; border-color: transparent; }
.modal-footer { border-top: none; }
#table-insert-col, #table-insert-row { background: var(--input-bg-color); border-radius: 2px; }
#megamenu-content { background-color: var(--bg-color); background-image: none !important; }
#top-titlebar { height: inherit; background-color: var(--bg-color); }
#megamenu-menu-sidebar { background-color: var(--bg-color); color: var(--text-color); }
.long-btn { width: inherit; min-width: 300px; border: 1px solid var(--text-color); border-radius: 6px; }
.megamenu-menu-panel h1 { margin-bottom: 3rem; text-align: left; }
.megamenu-menu-panel h1, .megamenu-menu-panel h2 { font-weight: normal; }
#recent-file-panel-search-input { height: 45px; border-top: none; border-right: none; border-left: none; border-image: initial; border-bottom: 1px solid var(--text-color); padding-left: 8px; }
#recent-file-panel-search-input::placeholder { color: var(--text-color); opacity: 0.5; }
.megamenu-menu-header { border-bottom: none; }
#recent-file-panel-action-btn { background: none; border: none; }
#recent-file-panel-action-btn-container { float: none; display: inline-block; }
#top-titlebar .toolbar-icon.btn.hover, #top-titlebar .toolbar-icon.btn:hover { background-color: var(--btn-hover-bg-color); color: var(--text-color); }
.megamenu-menu-panel .btn:hover { color: var(--text-color); background-color: var(--btn-hover-bg-color)  !important; }
#recent-file-panel tbody tr:nth-child(2n-1), .megamenu-menu-panel table thead, .megamenu-menu-panel table tr { background-color: transparent; }
.megamenu-menu-panel table { font-weight: normal; }
#megamenu-back-btn { color: var(--text-color); border: 1px solid var(--text-color); }
.megamenu-menu-header #megamenu-menu-header-title { color: var(--text-color); }
header, .context-menu, .megamenu-content, footer { font-family: var(--text-font); }
.ty-preferences select { padding-left: 2px; }
.preference-item-hint { font-size: 14px; }
a.ty-link { color: var(--a-color); margin: 0px 0.2rem; }
.cm-s-inner.CodeMirror { background: none; color: var(--code-block-color); }
.cm-s-inner span.cm-meta { color: rgb(187, 181, 41); }
.cm-s-inner span.cm-number { color: rgb(104, 151, 187); }
.cm-s-inner span.cm-keyword { color: rgb(204, 120, 50); }
.cm-s-inner span.cm-def { color: rgb(255, 215, 96); }
.cm-s-inner span.cm-variable { color: var(--code-block-color); }
.cm-s-inner span.cm-variable-2 { color: var(--code-block-color); }
.cm-s-inner span.cm-variable-3 { color: rgb(152, 118, 170); }
.cm-s-inner span.cm-type { color: rgb(170, 187, 204); }
.cm-s-inner span.cm-property { color: rgb(255, 198, 109); }
.cm-s-inner span.cm-operator { color: var(--code-block-color); }
.cm-s-inner span.cm-string { color: rgb(106, 135, 89); }
.cm-s-inner span.cm-string-2 { color: rgb(106, 135, 89); }
.cm-s-inner span.cm-comment { color: rgb(120, 120, 120); }
.cm-s-inner span.cm-link { color: rgb(204, 120, 50); }
.cm-s-inner span.cm-atom { color: rgb(204, 120, 50); }
.cm-s-inner span.cm-error { color: rgb(188, 63, 60); }
.cm-s-inner span.cm-tag { color: rgb(232, 191, 106); }
.cm-s-inner span.cm-quote { color: rgb(166, 226, 46); }
.cm-s-inner span.cm-attribute { color: rgb(152, 118, 170); }
.cm-s-inner span.cm-qualifier { color: rgb(106, 135, 89); }
.cm-s-inner span.cm-bracket { color: rgb(232, 191, 106); }
.cm-s-inner span.cm-builtin { color: rgb(255, 158, 89); }
.cm-s-inner span.cm-special { color: rgb(255, 158, 89); }
.cm-s-inner span.cm-matchhighlight { color: rgb(255, 255, 255); background-color: rgba(50, 89, 48, 0.7); font-weight: normal; }
.cm-s-inner span.cm-searching { color: rgb(255, 255, 255); background-color: rgba(61, 115, 59, 0.7); font-weight: normal; }
.cm-s-inner .CodeMirror-gutters { border-right: 1px solid rgba(120, 120, 120, 0.3); background: var(--code-block-bg-color); }
.cm-s-inner .CodeMirror-linenumber { color: rgb(88, 91, 93); }
.cm-s-inner .CodeMirror-matchingbracket { background-color: rgb(59, 81, 77); color: rgb(255, 239, 40) !important; }
.cm-s-inner .CodeMirror-selected { background: rgb(33, 66, 131) !important; }
.cm-s-inner .CodeMirror-selectedtext { background: rgb(33, 66, 131) !important; }
.cm-s-typora-default .CodeMirror-selectedtext { background: var(--select-text-bg-color)  !important; }
.cm-overlay.CodeMirror-selectedtext { background: var(--select-text-bg-color)  !important; }
.cm-s-inner div.CodeMirror-cursor { border-left: 1px solid var(--code-block-color); }
.cm-s-inner .cm-header, .cm-s-inner.cm-header { color: rgb(255, 215, 96); font-weight: normal; }





 .typora-export li, .typora-export p, .typora-export,  .footnote-line {white-space: normal;} 
</style>
</head>
<body class='typora-export os-windows' >
<div  id='write'  class = 'is-node'><h1><a name='header-n1042' class='md-header-anchor '></a>自动化测试-接口测试</h1><p>&nbsp;</p><h2><a name='header-n1045' class='md-header-anchor '></a>1. 接口测试</h2><h3><a name='header-n1046' class='md-header-anchor '></a>1.1 接口测试的背景</h3><p>应用程序编程接口（<code>Application Programming Interface，API</code>）是近年来最流行的技术之一，强大的Web应用程序和领先的移动应用程序都离不开后端强大的API。<strong>API技术的应用给系统开发带来了便利，但也对测试人员提出了更高的要求，如何以一种有效的方式测试这些API，并且确保它们按照预期运行，是目前测试人员面临的主要问题。</strong>大多数互联网公司和团队都在实施<strong>敏捷开发项目</strong>，在敏捷开发产品的生命周期中，测试人员需要一种简单、快捷的方法自动化测试API，甚至希望能够监控生产环境API（线上环境）的实时状况。</p><h3><a name='header-n1048' class='md-header-anchor '></a>1.2 接口测试的背景</h3><p>目前，软件系统的复杂度不断上升，传统功能测试的片面性及滞后性导致测试成本急剧增加，且测试效率大幅度下降<strong>，仅靠功能测试已难以保证项目质量及进度</strong>。而接口测试的应用，<code>恰好能使测试团队更早、更深入地介入项目，这样测试人员在项目初期就能发现系统深层次的问题，降低问题修复的时间成本。同时，由于接口的变更概率远远小于用户界面（UserInterface,UI）的变更概率，因此，接口测试自动化维护成本比UI自动化维护成本更低，接口测试相对更容易实现自动化测试持续集成，且可以减少回归测试的人力与时间成本，缩短测试周期，满足后端快速发布版本的需求。</code></p><h3><a name='header-n1050' class='md-header-anchor '></a>1.3 接口测试的原理</h3><blockquote><p>测试人员借助工具模拟客户端向服务器端发送请求报文，服务器端接收请求报文后，对相应的报文做出处理并向客户端返回应答，工具模拟客户端接收应答，然后测试人员检查应答是否准确。(我们主要使用Postman工具)</p></blockquote><p>&nbsp;</p><h3><a name='header-n1054' class='md-header-anchor '></a>1.4 接口测试的分类</h3><p>接口测试分类有许多种，按照范围划分:系统之间的接口和程序内部的接口</p><ul><li>系统之间的接口:多个内部系统之间的交互，内部系统与外部系统之间的交互</li><li>程序内部的接口:方法与方法之间，模块与模块之间的交互</li></ul><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\接口测试的分类.png' alt='1748260359267' referrerPolicy='no-referrer' /></p><h3><a name='header-n1062' class='md-header-anchor '></a>1.5 接口测试的范围</h3><p>关于接口测试的范围，主要从以下两方面进行介绍。</p><p><strong>（1）是否所有的接口都需要测试？</strong></p><p><span>	</span><strong>随着系统复杂度越来越高，接口越来越多，想完全覆盖所有接口是一件很困难的事情。通常情况下，主要测试最外层的两类接口：数据进入系统的接口（调用外部系统的参数为本系统使用）和数据流出系统的接口（验证系统处理后的数据是否正常）。</strong></p><p><strong>（2）被测接口需要测试哪些方面？</strong></p><p><span>	</span><strong>测试人员需要关注被测接口的功能是否实现、性能是否达标、安全性是否满足，重点关注数据的交换、传递、处理次数以及控制管理过程。</strong></p><p>&nbsp;</p><blockquote><p>依据所遵循协议的不同，常见接口可以分为以下3类。</p><p>（1）HTTP接口，它是基于超文本传输协议（HyperTextTransferProtocol，HTTP）开发的接口，但并不能排除没有使用其他协议。</p><p>（2）WebService接口，它是系统对外的接口，比如你要从别的网站或服务器上获取资源，一般来说，别人不会把数据库共享给你，他们会提供一个他们写好的方法，让你用来获取数据，你使用他们写好的方法就能引用他们提供的接口，从而达到同步数据的目的。</p><p>（3）RESTful接口，简称为REST，其描述了一个架构样式的网络系统，核心是面向资源。REST专门针对网络应用设计和开发方式，降低开发的复杂性，提高系统的可伸缩性。基于浏览器/服务器模式（Brower/Server，B/S）的软件系统接口大多数为HTTP接口，因此，本书将重点介绍HTTP接口的测试方法。要测试HTTP接口，首先需要了解HTTP、HTTP请求和响应的相关知识。</p><blockquote><p><a href='https://apifox.com/apiskills/restfulapi-vs-webservice/'>RESTful API 和 Web Service 之间的区别有哪些？</a></p></blockquote></blockquote><p>&nbsp;</p><h2><a name='header-n1077' class='md-header-anchor '></a>2. HTTP</h2><blockquote><ol start='' ><li>了解HTTP协议的特点</li><li>掌握URL的组成部分</li><li>掌握HTTP请求包含的内容 </li><li>掌握HTTP响应包含的内容</li><li>了解常见的响应状态码</li></ol></blockquote><p>&nbsp;</p><h3><a name='header-n1091' class='md-header-anchor '></a>2.1 HTTP协议简介</h3><p><code>HTTP:(HyperText Transfer Protocol)</code>超文本传输协议，是一个基于请求与响应模式的、应用层的协议，也是互联网上应用最为广泛的一种网络协议。</p><ul><li>（1）支持客户端/服务器模式。客户端向服务器请求服务时，只需传送请求方法和路径。常用的请求方法有GET、POST。每种方法规定的客户端与服务器联系的类型不同。</li><li>（2）简单。由于HTTP简单，服务器的程序规模小，因而通信速度比较快。</li><li>（3）灵活。HTTP允许传输任意类型的数据对象。正在传输的类型由ContentType加以标记。</li><li>（4）无连接。限制每次连接，使其只处理一个请求。服务器处理完客户端的请求，并收到客户端的应答后，即断开连接。采用这种方式可以节省传输时间。</li><li>（5）无状态。HTTP是无状态协议，无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息，则必须重新上传，这样可能导致每次连接传送的数据量增大，如果服务器不需要前面的信息，则应答就会比较快。</li></ul><h3><a name='header-n1104' class='md-header-anchor '></a>2.2 URL</h3><blockquote><p>URL:(Uniform Resource Locator)统一资源定位符，是互联网上标准资源的地址。HTTP使用URL来建立连接和传输数据。</p></blockquote><p><strong>URL格式</strong></p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="txt"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="txt"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">http://www.itcast.cn:8080/news/index.html?uid=123&amp;page=1</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">协议部分:“http”，常见的协议有HTTP，HTTPS、FTP等</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">域名部分:“www.itcast.cn”，也可以使用IP地址作为域名使用</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">端口部分:“8080”，端口可以省略，默认端口(HTTP:80，HTTPS:443，FTP:21)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">资源路径部分:“/news/index.html” </span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">查询参数部分:“uid=123&amp;page=1”，可以允许有多个参数，多个之间用“&amp;”作为分隔符</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 154px;"></div><div class="CodeMirror-gutters" style="display: none; height: 154px;"></div></div></div></pre><p>&nbsp;</p><h3><a name='header-n1110' class='md-header-anchor '></a>2.3 <strong>客户端 HTTP 请求</strong></h3><blockquote><p>URL只是标识资源的位置，而HTTP是用来提交和获取资源。客户端发送一个HTTP请求到服务器的请求消息，包括以下格式：请求行、请求头部、空行、请求数据四个部分组成，下图给出了请求报文的一般格式。</p><p>参考:<a href='https://zhuanlan.zhihu.com/p/346408612'>一篇让你彻底了解http请求报文和响应报文的结构 - 知乎</a></p><p>参考:<a href='https://mp.weixin.qq.com/s/xxxS5qG244F6L10Y_ZxyGQ' target='_blank' class='url'>https://mp.weixin.qq.com/s/xxxS5qG244F6L10Y_ZxyGQ</a></p></blockquote><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\http请求构成.jpg' alt='img' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><p><strong>真实的请求：</strong></p><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\http请求的详解.jpg' alt='img' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><p><strong>1.是请求方法</strong>，GET和POST是最常见的HTTP方法，除此以外还包括<code>DELETE、HEAD、OPTIONS、PUT、TRACE</code>。</p><figure><table><thead><tr><th>序号</th><th>方法</th><th>描述</th></tr></thead><tbody><tr><td>1</td><td>GET</td><td>请求指定的页面信息，并返回实体主体。</td></tr><tr><td>2</td><td>HEAD</td><td>类似于get请求，只不过返回的响应中没有具体的内容，用于获取报头</td></tr><tr><td>3</td><td>POST</td><td>向指定资源提交数据进行处理请求（例如提交表单或者上传文件），数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。</td></tr><tr><td>4</td><td>PUT</td><td>从客户端向服务器传送的数据取代指定的文档的内容。</td></tr><tr><td>5</td><td>DELETE</td><td>请求服务器删除指定的页面。</td></tr><tr><td>6</td><td>CONNECT</td><td>HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。</td></tr><tr><td>7</td><td>OPTIONS</td><td>允许客户端查看服务器的性能。</td></tr><tr><td>8</td><td>TRACE</td><td>回显服务器收到的请求，主要用于测试或诊断。</td></tr></tbody></table></figure><blockquote><p><strong>目前主要使用的HTTP 请求主要为 Get 和 Post 两种方法</strong></p></blockquote><p>&nbsp;</p><p><strong>2.为请求对应的URL地址</strong>，它和报文头的Host属性组成完整的请求URL，</p><p><strong>3.是协议名称及版本号</strong>。</p><p><strong>4.是HTTP的报文头</strong> ，报文头包含若干个属性，格式为“属性名:属性值”，服务端据此获取客户端的信息。</p><ul><li>Client-IP：提供了运行客户端的机器的IP地址</li><li>From：提供了客户端用户的E-mail地址</li><li>Host：给出了接收请求的服务器的主机名和端口号</li><li>Referer：提供了包含当前请求URI的文档的URL</li><li>UA-Color：提供了与客户端显示器的显示颜色有关的信息</li><li>UA-CPU：给出了客户端CPU的类型或制造商</li><li>UA-OS：给出了运行在客户端机器上的操作系统名称及版本</li><li>User-Agent：将发起请求的应用程序名称告知服务器</li><li>Accept：告诉服务器能够发送哪些媒体类型</li><li>Accept-Charset：告诉服务器能够发送哪些字符集</li><li>Accept-Encoding：告诉服务器能够发送哪些编码方式</li><li>Accept-Language：告诉服务器能够发送哪些语言</li><li>TE：告诉服务器可以使用那些扩展传输编码</li><li>Expect：允许客户端列出某请求所要求的服务器行为</li><li>Range：如果服务器支持范围请求，就请求资源的指定范围</li><li>Cookie：客户端用它向服务器传送数据</li><li><a href='https://zhida.zhihu.com/search?content_id=165109576&content_type=Article&match_order=1&q=Cookie2&zhida_source=entity'>Cookie2</a>：用来说明请求端支持的cookie版本</li></ul><p>&nbsp;</p><p><strong>5.是报文体</strong>，它将一个页面表单中的组件值通过<code>param1=value1&amp;m2=value2</code>的键值对形式编码成一个格式化串，它承载多个请求参数的数据。不但报文体可以传递请求参数，请求URL也可以通过类似于<code>/chapter15/user.html? param1=value1&amp;m2=value2</code>的方式传递请求参数。</p><h3><a name='header-n1201' class='md-header-anchor '></a>2.3 <strong>服务端 HTTP 响应</strong></h3><blockquote><p>HTTP的响应报文也由四部分组成（ 响应行+响应头+空行+响应体）：</p></blockquote><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\客户端http响应.jpg' alt='img' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><p><strong>真实数据：</strong></p><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\http响应数据.png' alt='1748314613581' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><p><strong>1.报文协议及版本</strong>；
<strong>2.状态码及状态描述</strong>；
状态码详解<a href='https://mp.weixin.qq.com/s/xxxS5qG244F6L10Y_ZxyGQ'>一篇让你彻底搞定HTTP方法与状态码</a>:</p><figure><table><thead><tr><th>序号</th><th>类别</th><th>原因短语</th></tr></thead><tbody><tr><td>1XX</td><td>Informational（信息性状态码）</td><td>接收的请求正在处理</td></tr><tr><td>2XX</td><td>Success（成功状态码）</td><td>请求正常处理完毕</td></tr><tr><td>3XX</td><td>Redirection（重定向状态码）</td><td>需要进行附加操作以完成请求</td></tr><tr><td>4XX</td><td>Client Error（客户端错误状态码）</td><td>服务器无法处理请求</td></tr><tr><td>5XX</td><td>Server Error（服务器错误状态码）</td><td>服务器处理请求出错</td></tr></tbody></table></figure><p>&nbsp;</p><p><strong>3.响应报文头</strong>，也是由多个属性组成；</p><ul><li>Age：(从最初创建开始)响应持续时间</li><li>Public：服务器为其资源支持的请求方法列表</li><li>Retry-After：如果资源不可用的话，在此日期或时间重试</li><li>Server：服务器应用程序软件的名称和版本</li><li>Title：对HTML文档来说，就是HTML文档的源端给出的标题</li><li>Warning：比原因短语更详细一些的警告报文</li><li>Accept-Ranges：对此资源来说，服务器可接受的范围类型</li><li>Vary：服务器会根据这些首部的内容挑选出最适合的资源版本发送给客户端</li><li>Proxy-Authenticate：来自代理的对客户端的质询列表</li><li>Set-Cookie：在客户端设置数据，以便服务器对客户端进行标识</li><li><a href='https://zhida.zhihu.com/search?content_id=165109576&content_type=Article&match_order=1&q=Set-Cookie2&zhida_source=entity'>Set-Cookie2</a>：与Set-Cookie类似</li><li>WWW-Authenticate：来自服务器的对客户端的质询列表</li></ul><p><strong>4.响应报文体</strong>，即我们真正要的“干货”。</p><p>&nbsp;</p><h2><a name='header-n1264' class='md-header-anchor '></a>3.接口规范 </h2><blockquote><p>思考:</p><p>如何让前端开发与后台接口开发人员更好的配合，提高工作效率?</p><p>无规矩不成方圆，制定接口规范</p></blockquote><p>&nbsp;</p><h3><a name='header-n1270' class='md-header-anchor '></a>3.1 传统接口风格 </h3><p>对用户进行操作的相关接口，包括增删改查</p><figure><table><thead><tr><th>操作</th><th>请求方式</th><th>URL</th><th>成功状态码</th></tr></thead><tbody><tr><td>查询某个用户</td><td>GET/POST</td><td><a href='http://127.0.0.1:8080/myweb/user/getUser?id=1' target='_blank' class='url'>http://127.0.0.1:8080/myweb/user/getUser?id=1</a><br><a href='http://127.0.0.1:8080/myweb/user/getById?id=1' target='_blank' class='url'>http://127.0.0.1:8080/myweb/user/getById?id=1</a><br><a href='http://127.0.0.1:8080/myweb/getUserById?id=1' target='_blank' class='url'>http://127.0.0.1:8080/myweb/getUserById?id=1</a></td><td>200</td></tr><tr><td>查询所有用户</td><td>GET/POST</td><td><a href='http://127.0.0.1:8080/myweb/user/getUserList' target='_blank' class='url'>http://127.0.0.1:8080/myweb/user/getUserList</a><br><a href='http://127.0.0.1:8080/myweb/user/getUsers' target='_blank' class='url'>http://127.0.0.1:8080/myweb/user/getUsers</a></td><td>200</td></tr><tr><td>添加用户</td><td>POST</td><td><a href='http://127.0.0.1:8080/myweb/user/addUser' target='_blank' class='url'>http://127.0.0.1:8080/myweb/user/addUser</a></td><td>200</td></tr><tr><td>修改用户</td><td>POST</td><td><a href='http://127.0.0.1:8080/myweb/user/updateUser' target='_blank' class='url'>http://127.0.0.1:8080/myweb/user/updateUser</a></td><td>200</td></tr><tr><td>删除用户</td><td>GET/POST</td><td><a href='http://127.0.0.1:8080/myweb/user/deleteUser?id=1' target='_blank' class='url'>http://127.0.0.1:8080/myweb/user/deleteUser?id=1</a></td><td>200</td></tr></tbody></table></figure><p>&nbsp;</p><h3><a name='header-n1304' class='md-header-anchor '></a>3.2 RESTful </h3><h3><a name='header-n1305' class='md-header-anchor '></a>3.2.1 定义</h3><blockquote><p>一种软件架构风格、设计风格，而不是标准，只是提供了一组设计原则和约束条件。
REST:即(Representational State Transfer)的缩写。词组的翻译是&quot;表现层状态转化&quot;。如果一个架构符合REST原则，就称它为RESTful架构。</p></blockquote><h3><a name='header-n1308' class='md-header-anchor '></a>3.2.2 RESTful接口风格</h3><p><strong>对用户进行操作的相关接口，包括增删改查</strong></p><figure><table><thead><tr><th>操作</th><th>请求方式</th><th>URL</th><th>成功状态码</th></tr></thead><tbody><tr><td>查询某个用户</td><td>GET</td><td><a href='http://127.0.0.1:8080/myweb/users/1' target='_blank' class='url'>http://127.0.0.1:8080/myweb/users/1</a></td><td>200</td></tr><tr><td>查询所有用户</td><td>GET</td><td><a href='http://127.0.0.1:8080/myweb/users' target='_blank' class='url'>http://127.0.0.1:8080/myweb/users</a></td><td>200</td></tr><tr><td>添加用户</td><td>POST</td><td><a href='http://127.0.0.1:8080/myweb/users' target='_blank' class='url'>http://127.0.0.1:8080/myweb/users</a></td><td>201</td></tr><tr><td>修改用户</td><td>PUT</td><td><a href='http://127.0.0.1:8080/myweb/users/1' target='_blank' class='url'>http://127.0.0.1:8080/myweb/users/1</a></td><td>201</td></tr><tr><td>删除用户</td><td>DELETE</td><td><a href='http://127.0.0.1:8080/myweb/users/1' target='_blank' class='url'>http://127.0.0.1:8080/myweb/users/1</a></td><td>204</td></tr></tbody></table></figure><h3><a name='header-n1341' class='md-header-anchor '></a>3.3 RESTful架构特点</h3><ol start='' ><li>每一个URL代表一种资源;</li><li>客户端和服务器之间，传递这种资源的某种表现层;</li><li>客户端通过四个HTTP动词，对服务器端资源进行操作，实现&quot;表现层状态转化&quot;; </li><li>接口之间传递的数据最常用格式为JSON。</li><li>常用的HTTP动词有下面四个:</li></ol><p>  <strong>GET:从服务器获取资源(一项或多项)</strong> 
  <strong>POST:在服务器新建一个资源</strong> 
  <strong>PUT:在服务器更新资源(客户端提供改变后的完整资源)</strong> 
  <strong>DELETE:从服务器删除资源</strong></p><p>&nbsp;</p><h2><a name='header-n1355' class='md-header-anchor '></a>4. 接口测试流程</h2><ol start='' ><li>需求分析：主要依据需求文档。</li><li>接口文档解析：通常由开发编写接口文档。</li><li>设计测试用例。</li><li>执行测试：使用工具或编写代码。</li><li>接口缺陷管理与跟踪。</li><li>生成测试报告。</li><li>接口自动化持续集成（可选）。</li></ol><p>&nbsp;</p><h2><a name='header-n1372' class='md-header-anchor '></a>5. Postman 的安装</h2><blockquote><p>直接双击：Postman-win64-Setup.exe （根据自己的电脑机器进行下载）</p><p>下载地址:<a href='https://www.postman.com/'>Postman: The World&#39;s Leading API Platform | Sign Up for Free</a></p></blockquote><p>&nbsp;</p><h2><a name='header-n1377' class='md-header-anchor '></a>6. Postman 的使用参考</h2><blockquote><p><a href='https://blog.csdn.net/qq_41099091/article/details/107319193' target='_blank' class='url'>https://blog.csdn.net/qq_41099091/article/details/107319193</a></p><p><a href='https://blog.csdn.net/zbj18314469395/article/details/106693615'>接口测试之Postman使用全图文指南(原来使用Postman测试API接口如此简单)_postman怎么测接口-CSDN博客</a></p><p>参考：电子书中对Postman 工具的介绍</p></blockquote><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\Postman界面介绍.png' alt='在这里插入图片描述' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><h2><a name='header-n1384' class='md-header-anchor '></a>7. Postman实战</h2><blockquote><p><a href='https://jsonplaceholder.typicode.com' target='_blank' class='url'>https://jsonplaceholder.typicode.com</a></p><p>在开发和测试过程中，有时候我们需要一些假数据来模拟真实场景。这时候，JSONPlaceholder就派上用场啦！它是一个免费的在线REST API，专门为测试和原型开发提供假数据。无论你是在GitHub的README中，还是在CodeSandbox的演示中，甚至是在Stack Overflow的代码示例中，都可以使用它来测试你的应用。</p><h3><a name='header-n1388' class='md-header-anchor '></a>JSONPlaceholder的资源</h3><p>JSONPlaceholder提供了六种常见的资源，简直是开发者的福音：</p><ul><li><code>/posts</code>：100个帖子</li><li><code>/comments</code>：500条评论</li><li><code>/albums</code>：100个相册</li><li><code>/photos</code>：5000张照片</li><li><code>/todos</code>：200个待办事项</li><li><code>/users</code>：10个用户</li></ul><p>这些资源之间还有关系哦，比如帖子有很多评论，相册有很多照片等等。</p><h3><a name='header-n1404' class='md-header-anchor '></a>如何使用JSONPlaceholder</h3><p>使用JSONPlaceholder相当简单，你可以通过各种HTTP方法来操作这些资源。比如：</p><ul><li>获取所有帖子：<code>GET /posts</code></li><li>获取特定帖子：<code>GET /posts/1</code></li><li>获取特定帖子的评论：<code>GET /posts/1/comments</code></li><li>根据帖子ID获取评论：<code>GET /comments?postId=1</code></li><li>创建新帖子：<code>POST /posts</code></li><li>更新帖子：<code>PUT /posts/1</code></li><li>部分更新帖子：<code>PATCH /posts/1</code></li><li>删除帖子：<code>DELETE /posts/1</code></li></ul></blockquote><p>&nbsp;</p><blockquote><p>提前给大家准备好勒接口文档和测试用例。</p></blockquote><hr /><h3><a name='header-n1427' class='md-header-anchor '></a>7.1 如何处理GET请求</h3><h4><a name='header-n1428' class='md-header-anchor '></a>7.1.1 无参的GET请求</h4><blockquote><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="txt"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="txt"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">获取所有帖子</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">- 请求方式：GET</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">- 请求路径：/posts</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">- 响应格式：</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">[</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> "userId": 1,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> "id": 1,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> "body": "quia et suscipit..."</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">},</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">...</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">]</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 286px;"></div><div class="CodeMirror-gutters" style="display: none; height: 286px;"></div></div></div></pre></blockquote><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\无参请求.png' alt='1748319701612' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><h4><a name='header-n1433' class='md-header-anchor '></a>7.1.2 有参的GET请求</h4><blockquote><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="txt"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="txt"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">获取特定id帖子</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">请求方式：GET</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">请求路径：/posts/{id}</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">响应格式：</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"userId": 1,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"id": 1,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"body": "quia et suscipit..."</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 220px;"></div><div class="CodeMirror-gutters" style="display: none; height: 220px;"></div></div></div></pre></blockquote><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\有参get请求.png' alt='1748319991064' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><h3><a name='header-n1438' class='md-header-anchor '></a>7.2 如何处理POST请求</h3><blockquote><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="txt" style="break-inside: unset;"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="txt"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation" style=""><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">创建新帖子</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">请求方式：POST</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">请求路径：/posts</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">请求体：</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"userId": 1,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"title": "New Post Title",</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"body": "Content of the new post"</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span cm-text="">​</span></span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">响应格式：</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">{</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"userId": 1,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"id": 101,</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"title": "New Post Title",</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">"body": "Content of the new post"</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">}</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 374px;"></div><div class="CodeMirror-gutters" style="display: none; height: 374px;"></div></div></div></pre></blockquote><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\post请求方式.png' alt='1748320190046' referrerPolicy='no-referrer' /></p><blockquote><p>这里的collections我们可以<strong>按功能模块命名</strong></p></blockquote><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\collects创建.png' alt='1748321677124' referrerPolicy='no-referrer' /></p><h2><a name='header-n1445' class='md-header-anchor '></a>8.配置环境变量</h2><blockquote><p><font size='4' color='red'> 为什么要设置postman的环境呢？</font></p><p>为了提高测试效率，减少频繁的重复操作</p><blockquote><p>更多使用方法:<a href='https://blog.csdn.net/qq_25112523/article/details/122329314'>不要再问我怎么设置Postman的环境变量和全局变量了_postman设置环境变量-CSDN博客</a></p></blockquote></blockquote><blockquote><p>举例：这个时候，如果有100个接口需要测试，并且这些接口需要在两个服务器上都再测试一遍，一个服务器地址是172.16.99.1一个服务器地址是172.16.99.5，这个时候如果不设置测试环境，那测试起来就会做很多重复的操作</p><p>好处 ：可以减少重复的输入相同的基地址，减少输入是的误操作几率，全部使用变量名url代替基地址输入；另一方面只需一个选择按钮就可以随时切换测试环境，无需对接口进行任何操作即可</p></blockquote><p><strong>在软件开发周期中，通常存在开发（Dev）、测试（Test）、生产（Prod）等不同环境，各环境的服务器地址（IP/域名）不同。通过环境变量存储这些地址（如<code>{{base_url}}</code>），无需手动修改每个请求的URL，只需切换环境即可动态适配不同服务器</strong></p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="txt"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="txt"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">DevEnvironment：http://192.168.1.21/api</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">TestEnvironment：http://api.example.com</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">ProdtEnvironment:http://api.xxxx.com</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 66px;"></div><div class="CodeMirror-gutters" style="display: none; height: 66px;"></div></div></div></pre><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\环境配置.png' alt='1748347853115' referrerPolicy='no-referrer' /></p><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\collections的使用.png' alt='1748349090777' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><h2><a name='header-n1459' class='md-header-anchor '></a>9.测试脚本编写和断言详解</h2><blockquote><p><font size='4' color='red'>测试确认API按预期工作，服务之间的集成运行可靠，并且新开发没有破坏任何现有功能。可以使用 JavaScript 为 Postman API 请求编写测试脚本。当 API 项目出现问题时，还可以使用测试代码来帮助调试过程。例如，可以编写一个测试，通过发送包含不完整数据或不正确参数的请求来验证 API 的错误处理。可以将测试添加到集合中的单个请求、集合和文件夹。Postman 包含添加然后修改以适合您的测试逻辑的代码片段。要将测试添加到请求，请打开请求并在“测试”选项卡中输入您的代码。测试将在请求运行后执行。您将能够在响应数据旁边的“测试结果”选项卡中看到输出。</font></p></blockquote><p><strong>示例:</strong></p><figure><table><thead><tr><th><strong>用例编号</strong></th><th><strong>测试目标</strong></th><th><strong>步骤描述</strong></th><th><strong>预期结果</strong></th><th><strong>验证点</strong></th></tr></thead><tbody><tr><td><strong>TC-COM-01</strong></td><td>验证获取所有评论</td><td>1. 调用 GET /comments</td><td>1. 状态码200 2. 返回数据类型为列表</td><td>响应包含预设的500条评论</td></tr></tbody></table></figure><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="js"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="js"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">pm</span>.<span class="cm-property">test</span>(<span class="cm-string">"断言返回的状态码为 201"</span>, <span class="cm-keyword">function</span> () {</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">pm</span>.<span class="cm-property">response</span>.<span class="cm-property">to</span>.<span class="cm-property">have</span>.<span class="cm-property">status</span>(<span class="cm-number">201</span>);</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">})</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 66px;"></div><div class="CodeMirror-gutters" style="display: none; height: 66px;"></div></div></div></pre><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\返回成功201的断言.png' alt='1748349754024' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><h3><a name='header-n1479' class='md-header-anchor '></a>9.1  pm.expect 格式化测试结果消息</h3><p>&nbsp;</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="js"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="js"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">pm</span>.<span class="cm-property">test</span>(<span class="cm-string">"当前使用的url是DevEnvironment"</span>,<span class="cm-keyword">function</span>(){</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">pm</span>.<span class="cm-property">expect</span>(<span class="cm-variable">pm</span>.<span class="cm-property">environment</span>.<span class="cm-property">get</span>(<span class="cm-string">"base_url"</span>)).<span class="cm-property">to</span>.<span class="cm-property">eql</span>(<span class="cm-string">"https://jsonplaceholder.typicode.com"</span>)</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">})</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 66px;"></div><div class="CodeMirror-gutters" style="display: none; height: 66px;"></div></div></div></pre><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\pm_expected.png' alt='1748350302689' referrerPolicy='no-referrer' /></p><p>可以使用不同的语法变体以您认为可读且适合您的应用程序和测试逻辑的方式编写测试。</p><pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="js"><div class="CodeMirror cm-s-inner CodeMirror-wrap" lang="js"><div style="overflow: hidden; position: relative; width: 3px; height: 0px; top: 0px; left: 4px;"><textarea autocorrect="off" autocapitalize="off" spellcheck="false" tabindex="0" style="position: absolute; bottom: -1em; padding: 0px; width: 1000px; height: 1em; outline: none;"></textarea></div><div class="CodeMirror-scrollbar-filler" cm-not-content="true"></div><div class="CodeMirror-gutter-filler" cm-not-content="true"></div><div class="CodeMirror-scroll" tabindex="-1"><div class="CodeMirror-sizer" style="margin-left: 0px; margin-bottom: 0px; border-right-width: 0px; padding-right: 0px; padding-bottom: 0px;"><div style="position: relative; top: 0px;"><div class="CodeMirror-lines" role="presentation"><div role="presentation" style="position: relative; outline: none;"><div class="CodeMirror-measure"><pre><span>xxxxxxxxxx</span></pre></div><div class="CodeMirror-measure"></div><div style="position: relative; z-index: 1;"></div><div class="CodeMirror-code" role="presentation"><div class="CodeMirror-activeline" style="position: relative;"><div class="CodeMirror-activeline-background CodeMirror-linebackground"></div><div class="CodeMirror-gutter-background CodeMirror-activeline-gutter" style="left: 0px; width: 0px;"></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"><span class="cm-variable">pm</span>.<span class="cm-property">test</span>(<span class="cm-string">"测试请求响应过程无误"</span>, <span class="cm-keyword">function</span> () {</span></pre></div><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;"> &nbsp; &nbsp;<span class="cm-variable">pm</span>.<span class="cm-property">response</span>.<span class="cm-property">to</span>.<span class="cm-property">not</span>.<span class="cm-property">be</span>.<span class="cm-property">error</span>;</span></pre><pre class=" CodeMirror-line " role="presentation"><span role="presentation" style="padding-right: 0.1px;">})</span></pre></div></div></div></div></div><div style="position: absolute; height: 0px; width: 1px; border-bottom: 0px solid transparent; top: 66px;"></div><div class="CodeMirror-gutters" style="display: none; height: 66px;"></div></div></div></pre><p>&nbsp;</p><figure><table><thead><tr><th><strong>用例编号</strong></th><th><strong>测试目标</strong></th><th><strong>步骤描述</strong></th><th><strong>预期结果</strong></th><th><strong>验证点</strong></th></tr></thead><tbody><tr><td><strong>TC-COM-05</strong></td><td>验证删除评论流程</td><td>1. 创建新评论 <br />2. 调用 DELETE /comments/{id} <br />3. 调用 GET /comments/{id}</td><td>1. 删除状态码200 2. 删除后查询状态码404</td><td>评论ID真实失效</td></tr></tbody></table></figure><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\postman使用方式.png' alt='1748350974297' referrerPolicy='no-referrer' /></p><p><img src='H:\教学\2025春季教学\软件质量保证与测试\ppt\04接口自动化测试\课程文档\figs\collects运行2.png' alt='1748351255022' referrerPolicy='no-referrer' /></p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p><p>&nbsp;</p></div>
</body>
</html>